package com.qingmeng.config;

import com.mybatisflex.codegen.config.GlobalConfig;
import com.mybatisflex.codegen.config.PackageConfig;
import com.mybatisflex.codegen.config.ServiceImplConfig;
import com.mybatisflex.codegen.entity.Table;
import com.mybatisflex.codegen.generator.IGenerator;
import com.mybatisflex.core.util.StringUtil;
import lombok.Getter;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

/**
 * @author qingmeng
 * @version 1.0.0
 * @Description 自定义 VO 生成器，用于生成 VO 类代码
 * @createTime 2025年08月27日 15:15:00
 */
@Getter
public class CustomVOGenerator implements IGenerator {
    /**
     * 模板路径
     */
    private String templatePath;

    /**
     * 默认构造函数，使用默认模板路径
     */
    public CustomVOGenerator() {
        this("/templates/vo.tpl");
    }

    /**
     * 带参构造函数，可指定模板路径
     *
     * @param templatePath 模板路径
     */
    public CustomVOGenerator(String templatePath) {
        this.templatePath = templatePath;
    }

    /**
     * 生成 VO 类代码
     *
     * @param table        表信息
     * @param globalConfig 全局配置
     */
    public void generate(Table table, GlobalConfig globalConfig) {
        PackageConfig packageConfig = globalConfig.getPackageConfig();
        ServiceImplConfig serviceImplConfig = globalConfig.getServiceImplConfig();
        String sourceDir = StringUtil.hasText(serviceImplConfig.getSourceDir()) ? serviceImplConfig.getSourceDir() : packageConfig.getSourceDir();
        String voPackagePath = packageConfig.getBasePackage().replace(".", "/") + "/vo";
        String voClassName = getEntityJavaFileName(table.getName(), globalConfig) +"VO";
        String voClassValueName = StringUtil.firstCharToLowerCase(voClassName);
        String voPackage = packageConfig.getBasePackage() +".vo";
        File voJavaFile = new File(sourceDir, voPackagePath + "/" + voClassName + globalConfig.getFileType());
        Map<String, Object> customConfig = globalConfig.getCustomConfig();
        customConfig.put("voClassName", voClassName);
        customConfig.put("voClassValueName", voClassValueName);
        customConfig.put("voPackage", voPackage);
        customConfig.put("isBase", false);

        if (!voJavaFile.exists() || serviceImplConfig.isOverwriteEnable()) {
            Map<String, Object> params = new HashMap(4);
            params.put("table", table);
            params.put("packageConfig", packageConfig);
            params.put("javadocConfig", globalConfig.getJavadocConfig());
            params.put("customConfig", customConfig);
            globalConfig.getTemplateConfig().getTemplate().generate(params, this.templatePath, voJavaFile);
        }
    }

    /**
     * 根据表名获取实体类名
     *
     * @param name         表名
     * @param globalConfig 全局配置
     * @return 实体类名
     */
    public String getEntityJavaFileName(String name, GlobalConfig globalConfig) {
        String entityJavaFileName = name;
        String tablePrefix = globalConfig.getStrategyConfig().getTablePrefix();
        if (tablePrefix != null) {
            String[] tablePrefixes = tablePrefix.split(",");

            for(String prefix : tablePrefixes) {
                String trimPrefix = prefix.trim();
                if (!trimPrefix.isEmpty() && name.startsWith(trimPrefix)) {
                    entityJavaFileName = entityJavaFileName.substring(trimPrefix.length());
                    break;
                }
            }
        }

        String tableSuffix = globalConfig.getStrategyConfig().getTableSuffix();
        if (tableSuffix != null) {
            String[] tableSuffixes = tableSuffix.split(",");

            for(String suffix : tableSuffixes) {
                String trimSuffix = suffix.trim();
                if (!trimSuffix.isEmpty() && name.endsWith(trimSuffix)) {
                    entityJavaFileName = entityJavaFileName.substring(0, entityJavaFileName.length() - trimSuffix.length());
                    break;
                }
            }
        }

        return StringUtil.firstCharToUpperCase(StringUtil.underlineToCamel(entityJavaFileName));
    }


    /**
     * 设置模板路径
     *
     * @param templatePath 模板路径
     */
    public void setTemplatePath(String templatePath) {
        this.templatePath = templatePath;
    }
}